package ch.ethz.smseth;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.database.Cursor;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;
import ch.ethz.smseth.ContactUtil.Contact;
import ch.ethz.smseth.activity.MainActivity;

public class ContactListAdapter extends BaseAdapter implements Filterable
{
	private MyFilter _filter;
	private ArrayList<Item> _items = new ArrayList<Item>();
	private LayoutInflater _inflater;

	public ContactListAdapter(Context ctx)
	{
		_filter = new MyFilter(ctx);
		_inflater = LayoutInflater.from(ctx);

	}

	@Override
	public Filter getFilter()
	{
		return _filter;
	}

	@Override
	public int getCount()
	{
		return _items.size();
	}

	@Override
	public Object getItem(int position)
	{
		return _items.get(position);
	}

	@Override
	public long getItemId(int position)
	{
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent)
	{
		Item item = _items.get(position);
		View view;
		if (convertView != null && (convertView.getId() == R.id.favoriteItemView) == item.isFavorite)
		{
			view = convertView;
		} else if (item.isFavorite)
		{
			view = _inflater.inflate(R.layout.favorite_item, parent, false);
		} else
		{
			view = _inflater.inflate(R.layout.contact_item, parent, false);
		}
		TextView nameView = (TextView) view.findViewById(R.id.nameView);
		TextView numberView = (TextView) view.findViewById(R.id.numberView);
		TextView labelView = (TextView) view.findViewById(R.id.labelView);
		nameView.setText(item.name);
		numberView.setText(item.number);
		labelView.setText(item.type);

		// set number
		view.setTag(item.number);
		return view;
	}

	public static class Item
	{
		public String name;
		public String number;
		public String type;
		public boolean isFavorite;
		
		@Override
		public String toString()
		{
			return name;
		}
	}

	private class MyFilter extends Filter
	{
		private ContactUtil _contactUtil;

		public MyFilter(Context ctx)
		{
			_contactUtil = ContactUtil.get(ctx);
		}

		@Override
		protected FilterResults performFiltering(CharSequence constraint)
		{
			FilterResults results = new FilterResults();
			ArrayList<Item> result = new ArrayList<Item>();
			addAll(queryFavorites(constraint), result);
			if (constraint != null && constraint.length() > 1)
			{
				addAll(queryPhone(constraint), result);
			}
			results.values = result;
			results.count = result.size();
			return results;
		}

		private void addAll(Cursor cursor, ArrayList<Item> items)
		{
			if (cursor.moveToFirst())
			{
				do
				{
					Item item = new Item();
					item.isFavorite = true;
					item.type = cursor.getString(3);
					item.number = cursor.getString(2);
					item.name = cursor.getString(1);
					items.add(item);
				} while (cursor.moveToNext());
			}
			cursor.close();
		}

		private void addAll(List<Contact> contacts, ArrayList<Item> items)
		{
			for (Contact c : contacts)
			{
				Item item = new Item();
				item.isFavorite = false;
				item.type = c.label;
				item.number = c.number;
				item.name = c.name;
				if (itemAlreadyAdded(items, item))
				{
					continue;
				}
				items.add(item);
			}
		}

		private boolean itemAlreadyAdded(ArrayList<Item> items, Item item)
		{
			for (int i = 0; i < items.size(); i++)
			{
				Item existing = items.get(i);
				if (existing.name.equals(item.name) && existing.type.equals(item.type))
					return true;
			}
			return false;
		}

		private List<Contact> queryPhone(CharSequence constraint)
		{
			return _contactUtil.fetchContacts(constraint.toString());
		}

		private Cursor queryFavorites(CharSequence constraint)
		{

			StringBuilder buffer = null;
			if (constraint != null)
			{
				String lowerCase = constraint.toString().toLowerCase();
				buffer = new StringBuilder();
				buffer.append("LOWER(");
				buffer.append(Favorites.NAME);
				buffer.append(") LIKE '" + lowerCase + "%' OR LOWER(");
				buffer.append(Favorites.NAME);
				buffer.append(") LIKE '% " + lowerCase + "%'");
			}

			String filter = buffer == null ? null : buffer.toString();
			return Favorites.getInstance().getReadableDatabase().query(Favorites.DATABASE_TABLE, MainActivity.FAVORITE_PROJECTION, filter, null, null, null, Favorites.LAST_USED + " DESC");
		}

		@SuppressWarnings("unchecked")
		@Override
		protected void publishResults(CharSequence constraint, FilterResults results)
		{
			if (results.values == null)
				_items = new ArrayList<Item>();
			else
				_items = (ArrayList<Item>) results.values;
			notifyDataSetChanged();
		}
	}
}
